﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <list>
#include<assert.h>
using namespace std;



void Test1()
{
	string a = "hello world";
	string b = a;      //VS环境下进行深拷贝
	if (a.c_str() == b.c_str())//c_str()是指向字符串的指针，因为a，b进行深拷贝，两指针不同
	{
		cout << "true" << endl;
	}
	else cout << "false" << endl;

	string c = b;
	c = "";
	if (a.c_str() == b.c_str())
	{
		cout << "true" << endl;
	}
	else cout << "false" << endl;

	a = "";
	if (a.c_str() == b.c_str())
	{
		cout << "true" << endl;
	}
	else cout << "false" << endl;
}


void Test2()
{
	string str1("very nice");
	cout << str1.size() << endl;

	str1.resize(str1.size()+2, '!');//增加string的长度，并初始化增加的部分
	cout << str1<< endl;

	str1.resize(4);
	cout << str1 << endl;

	str1.reserve(20);//扩大string的容量


	string str("Hello Bit.");
	str.reserve(111);
	str.resize(5);
	str.reserve(50);//缩小字符串容量被视为非绑定请求：容器实现可以自由优化，否则字符串容量大于 n。
	cout << str.size() << ":" << str.capacity() << endl;
}


void Test3()
{
	/*string str1("Please, replace the vowels in this sentence by asterisks.");
	size_t found = str1.find_first_of("abcdes");
	while (found != string::npos)
	{
		str1[found] = '*';
		found = str1.find_first_of("aeiou", found + 1);
	}
	cout << str1 << '\n';*/



	/*string str2 = "We think in generalities, but we live in details.";
	string str3 = str2.substr(3, 5);     
	size_t pos = str2.find("live");      
	string str4 = str2.substr(pos);    
	cout << str3 << endl << str4 << '\n';*/

	string str1 = "How are you?";
	string str2 = " ";
	string str3;
	int size1 = 0;
	int size2 = 0;

	while ((size1 = str1.find_first_of(str2, size1)) != string::npos)
	{
		str3 = str1.substr(size2, size1 - size2);
		cout << str3 << " ";
		size2 = ++size1;
	}

	if (size2 != str1.size())
	{
		str3 = str1.substr(size2, size1 - size2);
		cout << str3 << " ";
	}
	cout << endl;
}


void Test4()
{
	string str1("123456789");
	string::const_reverse_iterator it = str1.rbegin();
	while (it != str1.rend())
	{
		cout << *it << " ";
		it++;
	}
	const string str2 = "the";
	str1.insert(8, str2);
	cout << str1 << endl;
}



//int main()
//{
//	//Test1();
//    //Test2();
//	//Test3();
//	Test4();
//	
//	return 0;
//}



////////////////////////////////////////////////////////////////////////////////////////////////////////////


void test_string1()
{
	string str1("hello world ！！！");
	cout << str1 << endl;

	string str2(str1);//VS环境下深拷贝
	cout << str2 << endl;

	string str3(str2, 6);
	cout << str3 << endl;

	string str4(50, '#');
	cout << str4 << endl;
}

void test_string2()
{
	string s1;
	string s2 = "hello world!!!"; //隐式类型转化   构造+拷贝构造 -》优化 -- 直接构造

	//赋值函数重载
	string s3 = s2;
	s1 = "xxxx"; 
	s1 = 'y';
}

void test_string3()
{
	string s1("hello world ！！！");
	cout << s1 << endl;

	//遍历string
	for (size_t i = 0; i < s1.size(); i++)
	{
		s1[i]++;
	}
	cout << s1 << endl;

	const string s2("world");
	for (size_t i = 0; i < s2.size(); ++i)
	{
		//s2[i]++;
		cout << s2[i] << " ";
	}
	cout << endl;
	cout << s2 << endl;
}

void test_string4()
{
	string s1("hello world ！！！");
	string::iterator it = s1.begin();
	while(it != s1.end())
	{
		(*it)++;
		cout << *it << " ";
		++it;
	}
	cout << endl;
	cout << s1 << endl;


	string s2("string");
	// 范围for -- 自动迭代，自动判断结束
	// 依次取s中每个字符，赋值给ch
	for (auto ch : s2)
	{
		ch++;
		cout << ch << " ";
	}
	cout << endl;
	cout << s2 << endl;

	 string s3("string");
	for (auto& a : s3)
	{
		a++;
		cout << a << " ";
	}
	cout << endl;
	cout << s3 << endl;


	list<int> Lt(10, 1);
	list<int>::iterator lit = Lt.begin();
	while (lit != Lt.end())
	{
		cout << *lit << " ";
		lit++;
	}
	cout << endl;

	for (auto e : Lt)
	{
		cout << e << " ";
	}
	cout << endl;

	// 范围for底层其实就是迭代器
}

void test_string5()
{
	string st("hello world");
	string::reverse_iterator it = st.rbegin();
	while (it != st.rend())
	{
		*it = 'x';
		cout << *it << " ";
		it++;
	}
	cout << endl;

	const string str("hello world");
	string::const_reverse_iterator itr = str.rbegin();
	while (itr != str.rend())
	{
		cout << *itr << " ";
		++itr;
	}
	cout << endl;

	// reverse_iterator/const_reverse_iterator
}

void test_string6()
{
	string str("hello string");
	str.append("!!!");
	str.push_back('*');
	str.push_back('*');
	cout << str << endl;

	string st("aaaaa");
	str += "---";
	str + "sss";
	str += st;
	cout << str << endl;

	string stl("123456");
	str.append(++stl.begin(), --stl.end());//string& append (const string& str, size_t subpos, size_t sublen);
	cout << str << endl;

	string copy(stl.begin()+2,stl.end()-1);
	cout << copy << endl;

}

void test_string7()
{
	string st1("0123456789");
	string st2;
	cout << st1.max_size() << endl;
	cout << st2.max_size() << endl;

	cout << st1.size() << endl;
	cout << st2.size() << endl;

	cout << st1.capacity() << endl; 
	cout << st2.capacity() << endl;

	string st3;
	st3.reserve(100);//保留 开空间
	st3.reserve(50);
	st3.resize(200,'Z'); //     开空间 + 初始化

	cout << endl;

	size_t sz = st1.capacity();
	sz = st1.capacity();
	cout << "capacity changed: " << sz << '\n';
	cout << "making s grow:\n";
	for (int i = 0; i < 1000; ++i)
	{
		st1.push_back('c');
		if (sz != st1.capacity())
		{
			sz = st1.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}

}

void test_string8()
{
	string filename("test.cpp");
	cout << filename << endl;
	cout << filename.c_str() << endl;

	FILE* fout = fopen(filename.c_str(), "r");
	assert(fout);
	int ch = 0;
	while ((ch = fgetc(fout)) != EOF)
	{
		printf("%c", ch);
	}
}

void test_string9()
{
	string filename("test.cpp");
	cout << filename << endl;
	cout << filename.c_str() << endl;

	filename += '\0';
	filename += "string.cpp";
	cout << filename << endl; // string 对象size为准
	cout << filename.c_str() << endl; // 常量字符串对象\0

	cout << filename.size() << endl;
	string copy = filename;
	cout << copy << endl << endl;

	for (unsigned char ch = 0; ch < 128; ++ch)
	{
		cout << ch;
	}
	cout << endl;
	cout << "\\0" << endl;
}

void  DealUrl(const string& url)
{
	size_t pos1 = url.find("://");
	if (pos1 == string::npos)
	{
		cout << "非法url" << endl;
		return;
	}
	
	string protocol = url.substr(0, pos1);
	cout << protocol << endl;

	size_t pos2 = url.find('/', pos1 + 3);
	if (pos2 == string::npos)
	{
		cout << "非法url" << endl;
		return;
	}
	string domain = url.substr(pos1 + 3, pos2 - pos1 - 3);
	cout << domain << endl;

	string uri = url.substr(pos2 + 1);
	cout << uri << endl << endl;
}

void test_string10()
{
	string filename("test.cpp.tar.zip");
	// 后缀
	//size_t pos = filename.find('.');
	size_t pos = filename.rfind('.');
	if (pos != string::npos)
	{
		//string suff = filename.substr(pos, filename.size() - pos);
		string suff = filename.substr(pos);

		cout << suff << endl;
	}

	string url1 = "https://cplusplus.com/reference/string/string/";
	string url2 = "https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=ascall&step_word=&hs=0&pn=0&spn=0&di=7108135681917976577&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=2613959014%2C543572025&os=2740573600%2C1059518451&simid=2613959014%2C543572025&adpicid=0&lpn=0&ln=179&fr=&fmq=1660115697093_R&fm=&ic=undefined&s=undefined&hd=undefined&latest=undefined&copyright=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=https%3A%2F%2Fgimg2.baidu.com%2Fimage_search%2Fsrc%3Dhttp%3A%2F%2Fimg.php.cn%2Fupload%2Fimage%2F147%2F157%2F796%2F1593765739620093.png%26refer%3Dhttp%3A%2F%2Fimg.php.cn%26app%3D2002%26size%3Df9999%2C10000%26q%3Da80%26n%3D0%26g%3D0n%26fmt%3Dauto%3Fsec%3D1662707704%26t%3Da68cb238bbb3f99d0554098c785d526e&fromurl=ippr_z2C%24qAzdH3FAzdH3Fooo_z%26e3Brir_z%26e3BvgAzdH3FuwqAzdH3F9c9amd_z%26e3Bip4s&gsm=1&rpstart=0&rpnum=0&islist=&querylist=&nojc=undefined&dyTabStr=MCwzLDIsNCw2LDEsNSw3LDgsOQ%3D%3D";
	string url3 = "ftp://ftp.cs.umd.edu/pub/skipLists/skiplists.pdf";

	DealUrl(url1);
	DealUrl(url2);
	DealUrl(url3);
}

void test_string11()
{
	string s1;
	string s2;
	cin >> s1 >> s2;

	cout << (s1 > s2) << endl;
}

int main()
{
	//test_string1();
	//test_string2();
	//test_string3();
	//test_string4();
	//test_string5();
	//test_string6();
	//test_string7();
	test_string8();
	//test_string9();
	//test_string10();
	//test_string11();

	return 0;
}